package com.yuhang.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuhang.demo.dto.request.RuleAddRequest;
import com.yuhang.demo.dto.request.RuleUpdateRequest;
import com.yuhang.demo.dto.response.PageResult;
import com.yuhang.demo.dto.response.Result;
import com.yuhang.demo.entity.RuleInfo;
import com.yuhang.demo.enums.RuleTypeEnum;
import com.yuhang.demo.mapper.RuleInfoMapper;
import com.yuhang.demo.service.RuleConditionService;
import com.yuhang.demo.service.RuleDrugRelationService;
import com.yuhang.demo.service.RuleInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

@Service
public class RuleInfoServiceImpl extends ServiceImpl<RuleInfoMapper, RuleInfo> implements RuleInfoService {

    @Autowired
    private RuleInfoMapper ruleInfoMapper;

    @Lazy
    @Autowired
    private RuleConditionService conditionService;

    @Lazy
    @Autowired
    private RuleDrugRelationService drugRelationService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Long> addRule(RuleAddRequest request) {
        RuleTypeEnum ruleType = RuleTypeEnum.getByCode(request.getRuleType());
        if (ruleType == null) {
            return Result.fail(400, "规则类型无效");
        }

        // 1. 规则名称生成（严格对应表格前缀）
        String ruleName;
        if (RuleTypeEnum.DRUG_GENDER.equals(ruleType)) {
            ruleName = "药品区分性别使用--" + request.getItemName();
        } else {
            ruleName = "医疗服务项目儿童专用--" + request.getItemName();
        }

        // 2. 表格字段校验（严格匹配表格必填项）
        if (RuleTypeEnum.DRUG_GENDER.equals(ruleType)) {
            // 药品规则：校验“是否2024医保目录”和“限定性别”（表格第3、4列）
            if (request.getIs2024Medical() == null) {
                return Result.fail(400, "药品规则必须填写是否2024年医保目录内药品");
            }
            if (StringUtils.isBlank(request.getLimitGender())) {
                return Result.fail(400, "药品规则必须填写限定性别");
            }
        } else {
            // 医疗服务项目规则：校验表格第5列（项目代码）、第7列（TITLE）
            if (StringUtils.isBlank(request.getNationalItemCode())) {
                return Result.fail(400, "医疗服务项目规则必须填写国家项目代码");
            }
            if (StringUtils.isBlank(request.getTitle())) {
                return Result.fail(400, "医疗服务项目规则必须填写标题（TITLE）");
            }
        }

        // 3. 重复校验（基于表格唯一标识）
        LambdaQueryWrapper<RuleInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RuleInfo::getRuleType, request.getRuleType())
                .eq(RuleInfo::getItemName, request.getItemName());
        // 药品规则：按“药品通用名+限定性别”去重（表格第1+4列）
        if (RuleTypeEnum.DRUG_GENDER.equals(ruleType)) {
            wrapper.eq(RuleInfo::getLimitGender, request.getLimitGender());
        }
        // 医疗服务项目规则：按“项目名称+国家项目代码”去重（表格第2+5列）
        if (RuleTypeEnum.MEDICAL_CHILD.equals(ruleType)) {
            wrapper.eq(RuleInfo::getNationalItemCode, request.getNationalItemCode());
        }
        if (baseMapper.selectCount(wrapper) > 0) {
            return Result.fail(400, "表格中已存在相同规则，不可重复添加");
        }

        // 4. 封装实体并保存
        RuleInfo ruleInfo = new RuleInfo();
        BeanUtils.copyProperties(request, ruleInfo);
        ruleInfo.setRuleName(ruleName);
        ruleInfo.setDrugCodeCount(RuleTypeEnum.DRUG_GENDER.equals(ruleType) ? 0 : null); // 非药品规则无需该字段
        baseMapper.insert(ruleInfo);
        return Result.success(ruleInfo.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> updateRule(RuleUpdateRequest request) {
        // 1. 校验规则是否存在
        RuleInfo existRule = baseMapper.selectById(request.getId());
        if (existRule == null) {
            return Result.fail(404, "规则不存在");
        }

        // 2. 根据根据规则类型区分处理（核心修正）
        String ruleType = existRule.getRuleType(); // 从数据库获取当前规则类型（避免前端传递错误类型）

        // 3. 重复校验（根据规则类型执行不同的校验逻辑）
        if (RuleTypeEnum.DRUG_GENDER.getCode().equals(ruleType)) {
            // 3.1 药品规则：校验“项目名称+限定性别”是否重复
            // 仅需修改了名称或性别，才需要校验重复
            boolean isItemNameChanged = !existRule.getItemName().equals(request.getItemName());
            boolean isLimitGenderChanged = !Objects.equals(existRule.getLimitGender(), request.getLimitGender());

            if (isItemNameChanged || isLimitGenderChanged) {
                LambdaQueryWrapper<RuleInfo> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(RuleInfo::getItemName, request.getItemName())
                        .eq(RuleInfo::getLimitGender, request.getLimitGender())
                        .ne(RuleInfo::getId, request.getId()) // 排除当前规则
                        .eq(RuleInfo::getRuleType, ruleType); // 仅同类型内重复

                if (baseMapper.selectCount(wrapper) > 0) {
                    return Result.fail(400, "已存在该药品+限定性别的别的规则，不可重复");
                }
            }
        } else if (RuleTypeEnum.MEDICAL_CHILD.getCode().equals(ruleType)) {
            // 3.2 医疗服务项目规则：校验“项目名称+国家项目代码”是否重复
            // 仅当修改了名称或国家项目代码，才需要校验重复
            boolean isItemNameChanged = !existRule.getItemName().equals(request.getItemName());
            boolean isCodeChanged = !Objects.equals(existRule.getNationalItemCode(), request.getNationalItemCode());

            if (isItemNameChanged || isCodeChanged) {
                LambdaQueryWrapper<RuleInfo> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(RuleInfo::getItemName, request.getItemName())
                        .eq(RuleInfo::getNationalItemCode, request.getNationalItemCode())
                        .ne(RuleInfo::getId, request.getId()) // 排除当前规则
                        .eq(RuleInfo::getRuleType, ruleType); // 同类型内重复

                if (baseMapper.selectCount(wrapper) > 0) {
                    return Result.fail(400, "已存在该项目名称+国家项目代码的规则，不可重复");
                }
            }
        } else {
            return Result.fail(400, "规则类型无效");
        }

        // 4. 封装更新数据
        RuleInfo updateRule = new RuleInfo();
        BeanUtils.copyProperties(request, updateRule);

        // 5. 同步更新规则名称（根据类型动态生成）
        if (RuleTypeEnum.DRUG_GENDER.getCode().equals(ruleType)) {
            // 药品规则：规则名称 = 药品区分性别使用--[项目名称]
            updateRule.setRuleName("药品区分性别使用--" + request.getItemName());
        } else {
            // 医疗服务项目规则：规则名称 = 医疗服务项目儿童专用--[项目名称]
            updateRule.setRuleName("医疗服务项目儿童专用--" + request.getItemName());
        }

        // 6. 执行更新
        baseMapper.updateById(updateRule);
        return Result.success(true);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> deleteRule(Long id) {
        // 1. 校验规则是否存在
        RuleInfo existRule = baseMapper.selectById(id);
        if (existRule == null) {
            return Result.fail(404, "规则不存在");
        }

        // 2. 级联删除关联的条件和药品数据
        conditionService.deleteByRuleId(id);
        drugRelationService.deleteByRuleId(id);

        // 3. 逻辑删除规则
        baseMapper.deleteById(id);
        return Result.success(true);
    }

    @Override
    public Result<PageResult<RuleInfo>> getRulePage(
            Integer pageNum,
            Integer pageSize,
            String ruleType,
            String itemName, // 参数名从 drugGenericName 改为 itemName
            String limitGender,
            String nationalItemCode) { // 新增参数

        // 1. 构建分页参数
        Page<RuleInfo> page = new Page<>(pageNum, pageSize);

        // 2. 分页查询（传入新参数名和新增参数）
        Page<RuleInfo> rulePage = (Page<RuleInfo>) ruleInfoMapper.selectRulePage(
                page,
                ruleType,
                itemName, // 传递新参数名
                limitGender,
                nationalItemCode // 传递新增参数（医疗服务项目代码）
        );

        // 3. 封装分页结果（不变）
        PageResult<RuleInfo> pageResult = new PageResult<>();
        pageResult.setTotal(rulePage.getTotal());
        pageResult.setPages(rulePage.getPages());
        pageResult.setRecords(rulePage.getRecords());
        pageResult.setCurrent(pageNum);
        pageResult.setSize(pageSize);

        return Result.success(pageResult);
    }

    @Override
    public Result<RuleInfo> getRuleById(Long id) {
        RuleInfo ruleInfo = baseMapper.selectById(id);
        if (ruleInfo == null) {
            return Result.fail(404, "规则不存在");
        }
        return Result.success(ruleInfo);
    }
}
